﻿using System;
using System.Data.Spatial;
using System.IO;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using WAPISF;

namespace UnitTests
{
    /// <summary>
    /// These tests based on geometry primatives described http://en.wikipedia.org/wiki/Well-known_text
    /// </summary>
    [TestClass]
    public class JsonSpatialConverterTests
    {
        /// <summary>
        /// Implmentation method which calls the JsonSerializer
        /// </summary>
        /// <param name="geometry"></param>
        /// <returns>Json string</returns>
        private string JsonSerializerImpl(DbGeometry geometry)
        {
            JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings();
            JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            JsonWriter jsonWriter = new JsonTextWriter(sw);
            JsonSpatialConverter jsc = new JsonSpatialConverter();
            jsc.WriteJson(jsonWriter, geometry, serializer);
            return sw.ToString();
        }
        
        [TestMethod]
        public void TestPoint()
        {
            DbGeometry geometry = DbGeometry.PointFromText("POINT (30 10)", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"Point\",\"coordinates\":[30.0,10.0]}", output);
        }

        [TestMethod]
        public void TestLine()
        {
            DbGeometry geometry = DbGeometry.LineFromText("LINESTRING (30 10, 10 30, 40 40)", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"LineString\",\"coordinates\":[[30.0,10.0],[10.0,30.0],[40.0,40.0]]}", output);
        }

        [TestMethod]
        public void TestPolygon()
        {
            DbGeometry geometry = DbGeometry.PolygonFromText("POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"Polygon\",\"coordinates\":[[[30.0,10.0],[10.0,20.0],[20.0,40.0],[40.0,40.0],[30.0,10.0]]]}", output);
        }

        [TestMethod]
        public void TestPolygonWithInner()
        {
            DbGeometry geometry = DbGeometry.PolygonFromText("POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"Polygon\",\"coordinates\":[[[35.0,10.0],[10.0,20.0],[15.0,40.0],[45.0,45.0],[35.0,10.0]],[[20.0,30.0],[35.0,35.0],[30.0,20.0],[20.0,30.0]]]}", output);
        }

        [TestMethod]
        public void TestMultiPointA()
        {
            DbGeometry geometry = DbGeometry.MultiPointFromText("MULTIPOINT ((10 40), (40 30), (20 20), (30 10))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,40.0],[40.0,30.0],[20.0,20.0],[30.0,10.0]]}", output);
        }

        [TestMethod]
        public void TestMultiPointB()
        {
            DbGeometry geometry = DbGeometry.MultiPointFromText("MULTIPOINT (10 40, 40 30, 20 20, 30 10)", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,40.0],[40.0,30.0],[20.0,20.0],[30.0,10.0]]}", output);
        }

        [TestMethod]
        public void TestMultiLineString()
        {
            DbGeometry geometry = DbGeometry.MultiLineFromText("MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"MultiLineString\",\"coordinates\":[[[10.0,10.0],[20.0,20.0],[10.0,40.0]],[[40.0,40.0],[30.0,30.0],[40.0,20.0],[30.0,10.0]]]}", output);
        }

        [TestMethod]
        public void TestMultiPolygon()
        {
            DbGeometry geometry = DbGeometry.MultiPolygonFromText("MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[30.0,20.0],[10.0,40.0],[45.0,40.0],[30.0,20.0]]],[[[15.0,5.0],[40.0,10.0],[10.0,20.0],[5.0,10.0],[15.0,5.0]]]]}", output);
        }

        [TestMethod]
        public void TestMultiPolygonWithInner()
        {
            DbGeometry geometry = DbGeometry.MultiPolygonFromText("MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))", 4326); ;
            string output = JsonSerializerImpl(geometry);
            Assert.AreEqual("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[40.0,40.0],[20.0,45.0],[45.0,30.0],[40.0,40.0]]],[[[20.0,35.0],[45.0,20.0],[30.0,5.0],[10.0,10.0],[10.0,30.0],[20.0,35.0]],[[30.0,20.0],[20.0,25.0],[20.0,15.0],[30.0,20.0]]]]}", output);
        }

    }
}
